package com.quectel.aiot.service.impl;

import com.quectel.aiot.entity.Device;
import com.quectel.aiot.entity.Product;
import com.quectel.aiot.mapper.DeviceMapper;
import com.quectel.aiot.service.DeviceService;
import com.quectel.aiot.service.ProductService;
import com.quectel.aiot.util.SnowflakeIdWorker;
import com.quec.client.MgrClient;
import com.quec.model.device.request.DeviceListRequest;
import com.quec.model.device.response.DeviceListResponse;
import com.quec.model.device.response.DeviceListResponseBody;
import com.quec.model.product.request.ProductListRequest;
import com.quec.model.product.response.ProductListResponse;
import com.quec.model.product.response.ProductListResponseBody;
import com.quec.model.project.request.ProjectListRequest;
import com.quec.model.project.response.ProjectListResponse;
import com.quec.model.project.response.ProjectListResponseBody;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.quectel.aiot.mapper.PreImportDeviceMapper;
import com.quectel.aiot.entity.PreImportDevice;

import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class DeviceServiceImpl implements DeviceService {

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private MgrClient mgrClient;

    @Autowired
    private ProductService productService;

    @Autowired
    private PreImportDeviceMapper preImportDeviceMapper;

    // 雪花算法ID生成器
    private final SnowflakeIdWorker snowflakeIdWorker = new SnowflakeIdWorker(1, 1);


    // =================================================================
    // ===========   以下是您原有的、无需修改的设备同步等方法   ============
    // =================================================================

    @Override
    public void syncDevices(String productKey) {
        int pageSize = 100;
        int pageNum = 1;
        boolean hasMore = true;

        while (hasMore) {
            try {
                // 创建分页请求
                DeviceListRequest request = new DeviceListRequest(productKey);
                request.setPageSize(pageSize);
                request.setPageNum(pageNum);

                // 调用SDK获取设备列表
                DeviceListResponse response = mgrClient.getDeviceList(request);

                if (response != null && response.getSuccess() && response.getBody() != null) {
                    for (DeviceListResponseBody deviceInfo : response.getBody()) {
                        // 检查设备是否已存在
                        Device existingDevice = deviceMapper.findByProductKeyAndDeviceKey(productKey, deviceInfo.getDeviceKey());

                        // 如果设备已存在，保留其 role_id 和 voice_id
                        Device device;
                        if (existingDevice != null) {
                            device = existingDevice; // 从现有设备开始，避免覆盖角色信息
                        } else {
                            device = new Device();
                            device.setId(snowflakeIdWorker.nextId());
                            device.setCreateTime(new Date());
                        }

                        // 设置或更新通用字段
                        device.setAgentId(1L);
                        device.setActivate(false);
                        device.setName(deviceInfo.getDeviceName());
                        device.setProductKey(productKey);
                        device.setDeviceKey(deviceInfo.getDeviceKey());
                        device.setDeviceDesc(deviceInfo.getDeviceName());
                        device.setDeviceStatus(deviceInfo.getDeviceStatus());
                        device.setLastOnlineTime(deviceInfo.getLastConnTime() != null ?
                                new Date(deviceInfo.getLastConnTime()) : null);
                        device.setUpdateTime(new Date());

                        // sn自动补全逻辑
                        String sn = null;
                        if (existingDevice != null && existingDevice.getSn() != null && !existingDevice.getSn().isEmpty()) {
                            sn = existingDevice.getSn();
                        } else {
                            PreImportDevice preImport = preImportDeviceMapper.findByProductKeyAndDeviceKey(productKey, deviceInfo.getDeviceKey());
                            if (preImport != null && preImport.getSn() != null && !preImport.getSn().isEmpty()) {
                                sn = preImport.getSn();
                            }
                        }
                        device.setSn(sn);

                        if (existingDevice == null) {
                            deviceMapper.insert(device);
                            log.info("新增设备成功: {}", device.getDeviceKey());
                        } else {
                            deviceMapper.update(device);
                            log.info("更新设备成功: {}", device.getDeviceKey());
                        }
                    }

                    hasMore = response.getBody().size() == pageSize;
                    pageNum++;

                } else {
                    log.error("获取设备列表失败: {}", response != null ? response.getErrorMsg() : "response is null");
                    hasMore = false;
                }
            } catch (Exception e) {
                log.error("同步设备列表失败, productKey: {}, pageNum: {}", productKey, pageNum, e);
                hasMore = false;
            }
        }
    }

    @Override
    public void syncAllProductsDevices() {
        // ... 此处代码保持不变 ...
        try {
            ProjectListRequest projectListRequest = new ProjectListRequest();
            ProjectListResponse projectListResponse = mgrClient.getProjectList(projectListRequest);
            if (projectListResponse != null && projectListResponse.getSuccess() && projectListResponse.getBody() != null) {
                for (ProjectListResponseBody project : projectListResponse.getBody()) {
                    try {
                        ProductListRequest productListRequest = new ProductListRequest(project.getProjectId());
                        ProductListResponse productListResponse = mgrClient.getProductList(productListRequest);
                        if (productListResponse != null && productListResponse.getSuccess() && productListResponse.getBody() != null) {
                            for (ProductListResponseBody productInfo : productListResponse.getBody()) {
                                try {
                                    log.info("开始同步产品[{}]的设备列表", productInfo.getProductKey());
                                    syncDevices(productInfo.getProductKey());
                                    log.info("完成同步产品[{}]的设备列表", productInfo.getProductKey());
                                } catch (Exception e) {
                                    log.error("同步产品[{}]的设备列表失败", productInfo.getProductKey(), e);
                                    continue;
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.error("获取项目[{}]的产品列表失败", project.getProjectId(), e);
                        continue;
                    }
                }
            } else {
                log.error("获取项目列表失败: {}", projectListResponse != null ? projectListResponse.getErrorMsg() : "response is null");
            }
        } catch (Exception e) {
            log.error("同步所有产品设备列表失败", e);
            throw new RuntimeException("同步所有产品设备列表失败", e);
        }
    }

    @Override
    public List<Device> getDevicesByProductKey(String productKey) {
        return deviceMapper.findByProductKey(productKey);
    }

    @Override
    public List<Device> getAllDevices() {
        return deviceMapper.findAll();
    }

    @Override
    public Device getDeviceById(String deviceId) {
        return deviceMapper.findById(deviceId);
    }

    @Override
    public void deleteDevice(String deviceId) {
        deviceMapper.deleteById(deviceId);
    }

    @Override
    public void syncDevice(String productKey, String deviceKey) {
        // ... 此处代码保持不变 ...
        try {
            com.quec.model.device.request.DeviceBasicRequest request = new com.quec.model.device.request.DeviceBasicRequest(productKey, deviceKey);
            com.quec.model.device.response.DeviceDetailResponse response = mgrClient.getDeviceDetail(request);
            if (response != null && response.getSuccess() && response.getBody() != null) {
                com.quec.model.device.response.DeviceDetailResponseBody body = response.getBody();
                com.quec.model.device.response.DeviceInfoBody deviceInfo = body.getDeviceInfo();
                Device existingDevice = deviceMapper.findByProductKeyAndDeviceKey(productKey, deviceKey);

                Device device;
                if (existingDevice != null) {
                    device = existingDevice;
                } else {
                    device = new Device();
                    device.setId(snowflakeIdWorker.nextId());
                    device.setCreateTime(new Date());
                }

                device.setAgentId(1L);
                device.setActivate(false);
                device.setName(deviceInfo.getDeviceName());
                device.setProductKey(productKey);
                device.setDeviceKey(deviceKey);
                device.setDeviceDesc(deviceInfo.getDeviceName());
                device.setDeviceStatus(deviceInfo.getDeviceStatus());
                device.setLastOnlineTime(deviceInfo.getLastConnTime() != null ? new java.util.Date(deviceInfo.getLastConnTime()) : null);
                device.setUpdateTime(new java.util.Date());

                String sn = null;
                if (existingDevice != null && existingDevice.getSn() != null && !existingDevice.getSn().isEmpty()) {
                    sn = existingDevice.getSn();
                } else {
                    PreImportDevice preImport = preImportDeviceMapper.findByProductKeyAndDeviceKey(productKey, deviceKey);
                    if (preImport != null && preImport.getSn() != null && !preImport.getSn().isEmpty()) {
                        sn = preImport.getSn();
                    }
                }
                device.setSn(sn);

                if (existingDevice == null) {
                    deviceMapper.insert(device);
                    log.info("新增设备成功: {}", device.getDeviceKey());
                } else {
                    deviceMapper.update(device);
                    log.info("更新设备成功: {}", device.getDeviceKey());
                }
            } else {
                log.error("获取设备详情失败: {}", response != null ? response.getErrorMsg() : "response is null");
            }
        } catch (Exception e) {
            log.error("同步设备失败, productKey: {}, deviceKey: {}", productKey, deviceKey, e);
            throw new RuntimeException("同步设备失败", e);
        }
    }


    // =================================================================
    // ===========  以下是为实现新功能而新增的方法实现 (最终版)  ============
    // =================================================================

    /**
     * {@inheritDoc}
     */
    @Override
    public Device getDeviceWithCurrentRole(String pk, String dk) {
        log.info("正在根据 PK: {}, DK: {} 查询设备信息...", pk, dk);
        // 直接调用 mapper，一步到位获取包含 roleId 和 voiceId 的设备对象
        return deviceMapper.findByProductKeyAndDeviceKey(pk, dk);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean switchRoleAndVoice(String pk, String dk, Long roleId, Long voiceId) {
        log.info("正在为设备 (PK: {}, DK: {}) 切换角色为 roleId: {}, voiceId: {}", pk, dk, roleId, voiceId);

        // (可选的业务校验)
        // 在这里可以加入业务校验逻辑，比如：
        // 1. 检查 roleId 是否存在于 role 表。
        // 2. 检查 voiceId 是否存在于 voice 表。
        // 3. 检查 (roleId, voiceId) 的组合是否是一个业务上允许的“预设”组合（可以查询 device_role 表）。
        // 如果校验失败，可以直接 return false 或抛出业务异常。

        // 调用 mapper 执行更新操作
        int affectedRows = deviceMapper.updateCurrentRoleAndVoice(pk, dk, roleId, voiceId);

        // 如果受影响的行数大于0，说明更新成功
        if (affectedRows > 0) {
            log.info("设备 (PK: {}, DK: {}) 角色切换成功。", pk, dk);
            return true;
        } else {
            log.warn("设备 (PK: {}, DK: {}) 角色切换失败，没有找到匹配的设备记录。", pk, dk);
            return false;
        }
    }
}